--[[
Project:		TruRP
Author:			Martin 'Ploo' Pucilowski
File:			player.lua
Date:			
Description:	Handles all player specific functions and methods
--]]

local player = FindMetaTable("Player")

function GM:PlayerConnect( name, address )
	
end

function GM:PlayerAuthed( ply, SteamID, UniqueID )

end

function GM:PlayerInitialSpawn( ply )
	GAMEMODE:PlayerInitialize( ply )

	ply:SetTeam( OCCUPATION_CITIZEN )

	ply:ChatPrint("Welcome! It is " .. GetRPDay() .. ". " .. GetRPDate() .. " " .. GetRPTime() .. ".")
	ply:ChatPrint("Your name is " .. ply.RPName)

	return true
end

function GM:PlayerSpawn( ply )
    self.BaseClass:PlayerSpawn( ply )
	
	--ply:StorePlayerData()
	
    ply:SetGravity( 0.75 )
    ply:SetMaxHealth( 100, true )
	ply:SetArmor( 100 )

    ply:SetWalkSpeed( 300 )  
	ply:SetRunSpeed( 450 )  
end

function GM:PlayerLoadout( ply )
	ply:Give( "weapon_physcannon" )
	ply:Give( "weapon_physgun" )
	ply:Give( "hands" )
	ply:Give( "keys" )
	ply:Give( "gmod_camera" )
	ply:Give( "gmod_tool" )
	
	-- Loadout Occupation weapons  
	for _, v in pairs ( TRU.Occupations[ ply:Team() ].Weapons ) do
		ply:Give( v )
	end
	
	-- Switch to prefered weapon if they have it
	local cl_defaultweapon = ply:GetInfo( "cl_defaultweapon" )
	
	if ( ply:HasWeapon( cl_defaultweapon )  ) then
		--ply:SelectWeapon( cl_defaultweapon )
	end
	
	ply:SelectWeapon("hands")
end

function GM:PlayerSetModel( ply )
	local model = ""
	
	if ply:Team() == OCCUPATION_UNEMPLOYED then
		if not ply.Model then
			ply.Model = table.random( TRU.CitizenModels )
			model = ply.Model
		end
	else
		model = TRU.Occupations[ ply:Team() ].Model
	end
	
	util.PrecacheModel( model )
	ply:SetModel( model )
end

hook.Add("PlayerDeath", function(ply)
	UpdateMoney( ply, -100 )
	ply:ChatPrint("The hospital charges you $100 for their services")
end )

function GM:PlayerDisconnected(ply)
	--self.BaseClass:PlayerDisconnected(ply)
	
	ply:StorePlayerData()

	for _, v in ipairs( ents.GetAll() ) do
		if v:IsDoor() then
			v:RemoveOwner( ply )
		end
	end
end

function GM:GetFallDamage( ply, speed )
	if GetConVarNumber("mp_falldamage") == 1 then
		return speed / 8
	end
	return 20
end

function GM:CanPlayerSuicide( ply )
	if ply:IsSuperAdmin() then return true end
	ply:ChatPrint("Keep fighting, don't give up!")
	return false
end














-- F1 Menu (Player)
function GM:ShowHelp( ply )
	ply:ConCommand("RP_PlayerMenu")
end

-- F2 Menu
function GM:ShowTeam( ply )
	ply:ConCommand("RP_PlayerMenu", 3)
end

-- F3 Menu
function GM:ShowSpare1( ply )
	ply:ConCommand("RP_PlayerMenu", 4)
end

-- F4 Menu
function GM:ShowSpare2( ply )
	ply:ConCommand("RP_PropertyMenu")
end








function GM:PlayerInitialize( ply )
	ply = self

	ply.Characters = {  }
	
	-- Find out if we exist in the database...
	result = SQLQuery( "SELECT * FROM players WHERE steamid = '" .. ply:SteamID() .. "'" )
	
	if #result == 0 then
		print("Player not found in database. Entering player.")
		result = SQLQuery( "INSERT INTO players ( steamid, steamname) VALUES ('".. ply:SteamID() .."', '".. ply:Name() .."')" )
	end


	
	result = SQLQuery( "SELECT * FROM player_characters WHERE steamid = '" .. ply:SteamID() .. "'" )
	for k, v in pairs( result ) do
		ply.Characters[ v.character_id ] = {
			forename = v.forename,
			surname = v.surname,
			gender = v.gender,
			biography = v.biography					
		}	
	end
	
	ply:UpdateNWPlayerData()
end

function player:CreateCharacter( character )
	forename = "A"
	surname = "B"

	result = SQLQuery( "INSERT INTO characters ( steamid, forename, surname ) VALUES ('".. ply:SteamID() .."', '".. forename .."', '".. surname .."')" )
end

function player:ChooseCharacter( character_id )
	if not ply.Characters[ character_id ] then return end
	
	result = SQLQuery( "SELECT * FROM character_skills WHERE character_id = '" .. character_id .. "'" )
	for k, v in pairs( result ) do
		ply.Skills[ v.skill ] = v.xp
	end
	
	result = SQLQuery( "SELECT * FROM character_items WHERE character_id = '" .. character_id .. "'" )
	ply.Items = result
end

concommand.Add("RP_ChooseCharacter", function( ply, cmd, args)
	if not args[1] then return end
	ply:ChooseCharacter( args[1] )
end )




-- Health
function player:RestoreHealth( health )
	local health = math.Clamp( health, 0, ply:GetMaxHealth( ) )
	player:SetHealth( health )
end

-- Energy
function player:RestoreEnergy( energy )
	local energy = math.Clamp( energy, 0, ply:GetMaxEnergy( ) )
	player:SetEnergy( energy )
end

function player:SetEnergy( energy )
	local energy = math.Clamp( energy, 0, ply:GetMaxEnergy( ) )
	player.Energy = energy
end

function player:GetMaxEnergy()
	return player.MaxEnergy
end

function player:Energy()
	return player.Energy
end

-- Hunger
function player:RestoreHunger( hunger )
	local hunger = math.Clamp( hunger, 0, 100 )
	player:SetHunger( hunger )
end








function UpdateMoney( ply, amount, notify, overcharge )
	if amount >= 0 then
		-- They're getting money, give it to them, return true for success
		ply.Money = ply.Money + amount
		if notify then ply:ChatPrint("You earn $" .. amount .. ".") end
		return true
	elseif amount < 0 then
		-- They're losing money, will they be left on a negative balance?
		if ply.Money + amount < 0 then
			if overcharge then
				ply.Money = ply.Money + amount
				if notify then ply:ChatPrint("You are charged $" .. amount .. ".") end
				return true
			else
				if notify then ply:ChatPrint("You cannot afford that.") end
				return false
			end
		else
			ply.Money = ply.Money + amount
			if notify then ply:ChatPrint("You spend $" .. amount .. ".") end
			return true
		end
	end
end




























-- Weapon pickup
hook.Add( "PlayerSpawn", "PickupTimeout", function( ply )
	ply.PickupTimeout = CurTime() + 0.5
end )

function GM:PlayerCanPickupWeapon( ply, entity )
	if ( ply.PickupTimeout or 0 ) > CurTime() then return true end
	if ( ply.NextPickup or 0 ) > CurTime() then return false end

	if ply:KeyDown( IN_USE ) then
		if ply:CanReachEnt( ent, 96 ) then
			ply.NextPickup = CurTime() + 0.2
			return true
		end
	end
	return false
end

-- Weapon drop
local function DropWeapon( ply, cmd, args )
	local undroppableWeapons = { "weapon_physcannon", "weapon_physgun", "hands", "keys", "gmod_camera", "gmod_tool" }
	local weapon = ply:GetActiveWeapon()
	for k, v in pairs(undroppableWeapons) do
		if v == weapon:GetClass() then return false end
	end
	ply:DropWeapon( weapon )
end
command.Add("RP_DropWeapon", "drop", DropWeapon)


function player:UpdateNWPlayerData()
	self:SetNWString("RPName", self.RPName)
	self:SetNWInt("Money", self.Money)
end